﻿/*基于捂脸猫FaceCat框架 v1.0
上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using SkiaSharp;
using SkiaSharp.Views;
using SkiaSharp.Views.Desktop;

namespace FaceCat
{
    /// <summary>
    /// Gdi+绘图类
    /// </summary>
    public class SkiaPaint : FCPaint
    {
        /// <summary>
        /// 创建绘图类
        /// </summary>
        public SkiaPaint()
        {
        }

        /// <summary>
        /// 图层
        /// </summary>
        public SKCanvas m_canvas;

        private bool m_isClip;

        private bool m_isPathStart;

        public SKTypeface m_font = SKTypeface.FromFamilyName("Arial");

        public HashMap<String, SKImage> m_images = new HashMap<string, SKImage>();

        /// <summary>
        /// 绘图对象
        /// </summary>
        public SKPaint m_paint;

        /// <summary>
        /// 路径
        /// </summary>
        public SKPath m_path;

        /// <summary>
        /// 我的颜色
        /// </summary>
        public MyColor m_myColor = new MyColor();

        /// <summary>
        /// 横向偏移
        /// </summary>
        public int m_offsetX;

        /// <summary>
        /// 纵向偏移
        /// </summary>
        public int m_offsetY;

        /// <summary>
        /// 透明度
        /// </summary>
        public float m_opacity = 1;

        /// <summary>
        /// 刷新区域
        /// </summary>
        public FCRect m_pRect;

        /// <summary>
        /// 资源路径
        /// </summary>
        public String m_resourcePath;

        /// <summary>
        /// 旋转角度
        /// </summary>
        public int m_rotateAngle;

        /// <summary>
        /// 横向缩放因子
        /// </summary>
        public double m_scaleFactorX = 1;

        /// <summary>
        /// 纵向缩放因子
        /// </summary>
        public double m_scaleFactorY = 1;

        /// <summary>
        /// 窗口大小
        /// </summary>
        public FCRect m_wRect;

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void addArc(FCRect rect, float startAngle, float sweepAngle)
        {
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_path.AddArc(skRect, startAngle, sweepAngle);
            }
        }

        /// <summary>
        /// 添加贝赛尔曲线
        /// </summary>
        /// <param name="points">点阵</param>
        public override void addBezier(FCPoint[] points)
        {
        }

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="points">点阵</param>
        public override void addCurve(FCPoint[] points)
        {
        }

        /// <summary>
        /// 添加椭圆
        /// </summary>
        /// <param name="rect">矩形</param>
        public override void addEllipse(FCRect rect)
        {
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_path.AddOval(skRect);
            }
        }

        /// <summary>
        /// 添加直线
        /// </summary>
        /// <param name="x1">第一个点的横坐标</param>
        /// <param name="y1">第一个点的纵坐标</param>
        /// <param name="x2">第二个点的横坐标</param>
        /// <param name="y2">第二个点的纵坐标</param>
        public override void addLine(int x1, int y1, int x2, int y2)
        {
            int lx1 = x1 + m_offsetX;
            int ly1 = y1 + m_offsetY;
            int lx2 = x2 + m_offsetX;
            int ly2 = y2 + m_offsetY;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                lx1 = (int)(m_scaleFactorX * lx1);
                ly1 = (int)(m_scaleFactorY * ly1);
                lx2 = (int)(m_scaleFactorX * lx2);
                ly2 = (int)(m_scaleFactorY * ly2);
            }
            if (m_isPathStart)
            {
                m_isPathStart = false;
                m_path.MoveTo(lx1, ly1);
            }
            m_path.LineTo(lx2, ly2);
        }

        /// <summary>
        /// 添加矩形
        /// </summary>
        /// <param name="rect">区域</param>
        public override void addRect(FCRect rect)
        {
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_path.AddRect(skRect);
            }
        }

        /// <summary>
        /// 添加扇形
        /// </summary>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void addPie(FCRect rect, float startAngle, float sweepAngle)
        {
        }

        /// <summary>
        /// 添加文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>
        /// <param name="rect">区域</param>
        public override void addText(String text, FCFont font, FCRect rect, int width)
        {
            
        }

        /// <summary>
        /// 缩放因子生效
        /// </summary>
        public void affectScaleFactor(ref SKRect skRect)
        {
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                skRect = new SKRect((int)(skRect.Left * m_scaleFactorX),
                    (int)(skRect.Top * m_scaleFactorY), (int)(skRect.Right * m_scaleFactorX),
                    (int)(skRect.Bottom * m_scaleFactorY));
            }
        }

        /// <summary>
        /// 开始导出
        /// </summary>
        /// <param name="exportPath">路径</param>
        /// <param name="rect">区域</param>
        public override void beginExport(String exportPath, FCRect rect)
        {
            
        }
        /// <summary>
        /// 开始绘图
        /// </summary>
        /// <param name="hdc">HDC</param>
        /// <param name="wRect">窗体区域</param>
        /// <param name="pRect">刷新区域</param>
        public override void beginPaint(IntPtr hdc, FCRect wRect, FCRect pRect)
        {
            m_pRect = pRect;
            m_wRect = wRect;
            m_opacity = 1;
            m_resourcePath = null;
            if(m_paint == null)
            {
                m_paint = new SKPaint();
                m_paint.IsAntialias = true;
            }
            m_isClip = false;
            m_isPathStart = false;
        }

        /// <summary>
        /// 开始一段路径
        /// </summary>
        public override void beginPath()
        {
            m_path = new SKPath();
            m_isPathStart = true;
        }

        /// <summary>
        /// 清除缓存
        /// </summary>
        public override void clearCaches()
        {
            foreach(SKImage image in m_images.Values)
            {
                image.Dispose();
            }
            m_images.clear();
        }

        /// <summary>
        /// 裁剪路径
        /// </summary>
        public override void clipPath()
        {
        }

        /// <summary>
        /// 闭合路径
        /// </summary>
        public override void closeFigure()
        {
            m_path.Close();
        }

        /// <summary>
        /// 结束一段路径
        /// </summary>
        public override void closePath()
        {
            if (m_path != null)
            {
                m_path.Dispose();
                m_path = null;
            }
            m_isPathStart = false;
        }

        /// <summary>
        /// 销毁对象
        /// </summary>
        public override void delete()
        {
            clearCaches();
            if(m_paint != null)
            {
                m_paint.Dispose();
                m_paint = null;
            }
        }

        /// <summary>
        /// 绘制弧线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void drawArc(long dwPenColor, float width, int style, FCRect rect, float startAngle, float sweepAngle)
        {
            if (dwPenColor == FCColor.None) return;
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_paint.Color = getSkColor(dwPenColor);
                m_paint.Style = SKPaintStyle.Stroke;
                float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                m_paint.StrokeWidth = lineWidth;
                m_canvas.DrawArc(skRect, startAngle, sweepAngle, true, m_paint);
            }
        }

        /// <summary>
        /// 设置贝赛尔曲线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">坐标阵1</param>
        public override void drawBezier(long dwPenColor, float width, int style, FCPoint[] points)
        {
        }

        /// <summary>
        /// 绘制曲线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">坐标阵</param>
        public override void drawCurve(long dwPenColor, float width, int style, FCPoint[] points)
        {
        }


        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        public override void drawEllipse(long dwPenColor, float width, int style, FCRect rect)
        {
            if (dwPenColor == FCColor.None) return;
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_paint.Color = getSkColor(dwPenColor);
                m_paint.Style = SKPaintStyle.Stroke;
                float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                m_paint.StrokeWidth = lineWidth;
                m_canvas.DrawOval(skRect, m_paint);
            }
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void drawEllipse(long dwPenColor, float width, int style, int left, int top, int right, int bottom)
        {
            FCRect rect = new FCRect(left, top, right, bottom);
            drawEllipse(dwPenColor, width, style, rect);
        }

        /// <summary>
        /// 绘制图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <param name="rect">绘制区域</param>
        public override void drawImage(String imagePath, FCRect rect)
        {
            try
            {
                int dw = rect.right - rect.left, dh = rect.bottom - rect.top;
                String imageKey = imagePath;
                int rw = rect.right - rect.left;
                if (rw < 1) rw = 1;
                int rh = rect.bottom - rect.top;
                if (rh < 1) rh = 1;
                SKImage drawImage = null;
                if (m_images.containsKey(imageKey))
                {
                    drawImage = m_images.get(imageKey);
                }
                else
                {
                    drawImage = SKImage.FromEncodedData(imagePath);
                    if (drawImage != null)
                    {
                        m_images.put(imageKey, drawImage);
                    }
                }
                if (drawImage != null)
                {
                    SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
                    affectScaleFactor(ref skRect);
                    if (skRect.Width > 0 && skRect.Height > 0)
                    {
                        m_canvas.DrawImage(drawImage, skRect);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 绘制直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="x1">第一个点的横坐标</param>
        /// <param name="y1">第一个点的纵坐标</param>
        /// <param name="x2">第二个点的横坐标</param>
        /// <param name="y2">第二个点的纵坐标</param>
        public override void drawLine(long dwPenColor, float width, int style, int x1, int y1, int x2, int y2)
        {
            if (dwPenColor == FCColor.None) return;
            int lx1 = x1 + m_offsetX;
            int ly1 = y1 + m_offsetY;
            int lx2 = x2 + m_offsetX;
            int ly2 = y2 + m_offsetY;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                lx1 = (int)(m_scaleFactorX * lx1);
                ly1 = (int)(m_scaleFactorY * ly1);
                lx2 = (int)(m_scaleFactorX * lx2);
                ly2 = (int)(m_scaleFactorY * ly2);
            }
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Stroke;
            float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
            m_paint.StrokeWidth = lineWidth;
            m_canvas.DrawLine(lx1, ly1, lx2, ly2, m_paint);
        }

        /// <summary>
        /// 绘制直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="x">第一个点的坐标</param>
        /// <param name="y">第二个点的坐标</param>
        public override void drawLine(long dwPenColor, float width, int style, FCPoint x, FCPoint y)
        {
            drawLine(dwPenColor, width, style, x.x, x.y, y.x, y.y);
        }

        /// <summary>
        /// 绘制路径
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        public override void drawPath(long dwPenColor, float width, int style)
        {
            if (dwPenColor == FCColor.None) return;
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Stroke;
            float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
            m_paint.StrokeWidth = lineWidth;
            m_canvas.DrawPath(m_path, m_paint);
        }

        /// <summary>
        /// 绘制扇形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void drawPie(long dwPenColor, float width, int style, FCRect rect, float startAngle, float sweepAngle)
        {
        }

        /// <summary>
        /// 绘制多边形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">点的数组</param>
        public override void drawPolygon(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            SKPath path = new SKPath();
            for (int i = 0; i < points.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                if (i == 0)
                {
                    path.MoveTo(x, y);
                }
                else
                {
                    path.LineTo(x, y);
                }
            }
            path.Close();
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Stroke;
            float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
            m_paint.StrokeWidth = lineWidth;
            m_canvas.DrawPath(path, m_paint);
            path.Dispose();
        }

        /// <summary>
        /// 绘制大量直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">点集</param>
        public override void drawPolyline(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            SKPath path = new SKPath();
            for (int i = 0; i < points.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                if (i == 0)
                {
                    path.MoveTo(x, y);
                }
                else
                {
                    path.LineTo(x, y);
                }
            }
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Stroke;
            float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
            m_paint.StrokeWidth = lineWidth;
            m_canvas.DrawPath(path, m_paint);
            path.Dispose();
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        public override void drawRect(long dwPenColor, float width, int style, FCRect rect)
        {
            if (dwPenColor == FCColor.None) return;
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX - 1, rect.bottom + m_offsetY - 1);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_paint.Color = getSkColor(dwPenColor);
                m_paint.Style = SKPaintStyle.Stroke;
                float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                m_paint.StrokeWidth = lineWidth;
                m_canvas.DrawRect(skRect, m_paint);
            }
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void drawRect(long dwPenColor, float width, int style, int left, int top, int right, int bottom)
        {
            FCRect rect = new FCRect(left, top, right, bottom);
            drawRect(dwPenColor, width, style, rect);
        }

        /// <summary>
        /// 绘制圆角矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="cornerRadius">边角半径</param>
        public override void drawRoundRect(long dwPenColor, float width, int style, FCRect rect, int cornerRadius)
        {
            if (cornerRadius > 0)
            {
                if (dwPenColor == FCColor.None) return;
                SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX - 1, rect.bottom + m_offsetY - 1);
                affectScaleFactor(ref skRect);
                if (skRect.Width > 0 && skRect.Height > 0)
                {
                    m_paint.Color = getSkColor(dwPenColor);
                    m_paint.Style = SKPaintStyle.Stroke;
                    float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                    m_paint.StrokeWidth = lineWidth;
                    m_canvas.DrawRoundRect(skRect, cornerRadius, cornerRadius, m_paint);
                }
            }
            else
            {
                drawRect(dwPenColor, width, style, rect);
            }
        }

        /// <summary>
        /// 绘制文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawText(String text, long dwPenColor, FCFont font, FCRect rect, int width)
        {
            String fontFamily = font.m_fontFamily;
            String newFont = "";
            if (fontFamily == "Default")
            {
                newFont = MyColor.getSystemFont();
            }
            else
            {
                newFont = font.m_fontFamily;
            }
            if (m_font.FamilyName != newFont)
            {
                m_paint.Typeface = SKTypeface.FromFamilyName(newFont);
            }
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Fill;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                int strX = (int)(m_scaleFactorX * (rect.left + m_offsetX));
                int strY = (int)(m_scaleFactorY * (rect.top + m_offsetY));
                float fontSize = (float)(font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                m_paint.TextSize = scaleFont.m_fontSize + 2;
                SKFontMetrics fm = m_paint.FontMetrics;
                float baseLineY = ((int)((rect.bottom + m_offsetY) * m_scaleFactorY) + (int)((rect.top + m_offsetY) * m_scaleFactorY) - fm.Bottom - fm.Top) / 2;
                SKPoint skPoint = new SKPoint(strX, baseLineY);
                m_canvas.DrawText(text, skPoint, m_paint);
            }
            else
            {
                m_paint.TextSize = font.m_fontSize + 2;
                SKFontMetrics fm = m_paint.FontMetrics;
                float baseLineY = ((rect.bottom + m_offsetY) + (rect.top + m_offsetY) - fm.Bottom - fm.Top) / 2;
                SKPoint skPoint = new SKPoint(rect.left + m_offsetX, baseLineY);
                m_canvas.DrawText(text, skPoint, m_paint);
            }
        }

        /// <summary>
        /// 绘制文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawText(String text, long dwPenColor, FCFont font, FCRectF rect, int width)
        {
            drawText(text, dwPenColor, font, new FCRect(rect.left, rect.top, rect.right, rect.bottom), width);
        }

        /// <summary>
        /// 绘制自动省略结尾的文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawTextAutoEllipsis(String text, long dwPenColor, FCFont font, FCRect rect)
        {
            drawText(text, dwPenColor, font, rect, -1);
        }

        /// <summary>
        /// 结束导出
        /// </summary>
        public override void endExport()
        {
            m_offsetX = 0;
            m_offsetY = 0;
            m_opacity = 1;
            m_resourcePath = null;
        }

        /// <summary>
        /// 结束绘图
        /// </summary>
        public override void endPaint()
        {
            m_offsetX = 0;
            m_offsetY = 0;
            m_opacity = 1;
            m_resourcePath = "";
        }

        /// <summary>
        /// 反裁剪路径
        /// </summary>
        public override void excludeClipPath()
        {
        }

        /// <summary>
        /// 设置裁剪区域
        /// </summary>
        /// <param name="rect">区域</param>
        public virtual void excludeClip(FCRect rect)
        {
        }

        /// <summary>
        /// 填充椭圆
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        public override void fillEllipse(long dwPenColor, FCRect rect)
        {
            fillEllipse(dwPenColor, rect.left, rect.top, rect.right, rect.bottom);
        }

        /// <summary>
        /// 填充椭圆
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void fillEllipse(long dwPenColor, int left, int top, int right, int bottom)
        {
            if (dwPenColor == FCColor.None) return;
            SKRect skRect = new SKRect(left + m_offsetX, top + m_offsetY, right + m_offsetX, bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_paint.Color = getSkColor(dwPenColor);
                m_paint.Style = SKPaintStyle.Fill;
                m_canvas.DrawOval(skRect, m_paint);
            }
        }

        /// <summary>
        /// 绘制渐变椭圆
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">矩形</param>
        /// <param name="angle">角度</param>
        public override void fillGradientEllipse(long dwFirst, long dwSecond, FCRect rect, int angle)
        {
            fillEllipse(dwFirst, rect);
        }

        /// <summary>
        /// 填充渐变路径
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="points">点的集合</param>
        /// <param name="angle">角度</param>
        public override void fillGradientPath(long dwFirst, long dwSecond, FCRect rect, int angle)
        {
            fillPath(dwFirst);
        }

        /// <summary>
        /// 绘制渐变的多边形
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">点的集合</param>
        /// <param name="angle">角度</param>
        public override void fillGradientPolygon(long dwFirst, long dwSecond, FCPoint[] points, int angle)
        {
            fillPolygon(dwFirst, points);
        }

        /// <summary>
        /// 绘制渐变矩形
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">矩形</param>
        /// <param name="cornerRadius">边角半径</param>
        /// <param name="angle">角度</param>
        public override void fillGradientRect(long dwFirst, long dwSecond, FCRect rect, int cornerRadius, int angle)
        {
            fillRect(dwFirst, rect);
        }

        /// <summary>
        /// 填充路径
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        public override void fillPath(long dwPenColor)
        {
            if (dwPenColor == FCColor.None) return;
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Fill;
            m_canvas.DrawPath(m_path, m_paint);
        }

        /// <summary>
        /// 绘制扇形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void fillPie(long dwPenColor, FCRect rect, float startAngle, float sweepAngle)
        {
        }

        /// <summary>
        /// 填充多边形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="points">点的数组</param>
        public override void fillPolygon(long dwPenColor, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            SKPath path = new SKPath();
            for (int i = 0; i < points.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                if (i == 0)
                {
                    path.MoveTo(x, y);
                }
                else
                {
                    path.LineTo(x, y);
                }
            }
            path.Close();
            m_paint.Color = getSkColor(dwPenColor);
            m_paint.Style = SKPaintStyle.Fill;
            m_canvas.DrawPath(path, m_paint);
            path.Dispose();
        }

        /// <summary>
        /// 填充矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        public override void fillRect(long dwPenColor, FCRect rect)
        {
            fillRect(dwPenColor, rect.left, rect.top, rect.right, rect.bottom);
        }

        /// <summary>
        /// 填充矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void fillRect(long dwPenColor, int left, int top, int right, int bottom)
        {
            if (dwPenColor == FCColor.None) return;
            SKRect skRect = new SKRect(left + m_offsetX, top + m_offsetY, right + m_offsetX, bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_paint.Color = getSkColor(dwPenColor);
                m_paint.Style = SKPaintStyle.Fill;
                m_canvas.DrawRect(skRect, m_paint);
            }
        }

        /// <summary>
        /// 填充圆角矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="cornerRadius">边角半径</param>
        public override void fillRoundRect(long dwPenColor, FCRect rect, int cornerRadius)
        {
            if (cornerRadius > 0)
            {
                if (dwPenColor == FCColor.None) return;
                SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
                affectScaleFactor(ref skRect);
                if (skRect.Width > 0 && skRect.Height > 0)
                {
                    m_paint.Color = getSkColor(dwPenColor);
                    m_paint.Style = SKPaintStyle.Fill;
                    m_canvas.DrawRoundRect(skRect, cornerRadius, cornerRadius, m_paint);
                }
            }
            else
            {
                fillRect(dwPenColor, rect);
            }
        }

        /// <summary>
        /// 获取Skia的颜色
        /// </summary>
        /// <param name="dwPenColor"></param>
        /// <returns></returns>
        public SKColor getSkColor(long dwPenColor)
        {
            long c = dwPenColor;
            if (dwPenColor < FCColor.None)
            {
                dwPenColor = m_myColor.getUserColor(dwPenColor);
            }
            int a = 255;
            if (dwPenColor < 0)
            {
                dwPenColor = Math.Abs(dwPenColor);
                a = (int)(dwPenColor - dwPenColor / 1000 * 1000);
                dwPenColor /= 1000;
            }
            if (m_opacity < 1)
            {
                a = (int)(a * m_opacity);
            }
            int r = (int)(dwPenColor & 0xff);
            int g = (int)((dwPenColor >> 8) & 0xff);
            int b = (int)((dwPenColor >> 0x10) & 0xff);
            return new SKColor((byte)r, (byte)g, (byte)b, (byte)a);
        }

        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="dwPenColor">输入颜色</param>
        /// <returns>输出颜色</returns>
        public override long getColor(long dwPenColor)
        {
            long color = dwPenColor;
            if (dwPenColor < FCColor.None)
            {
                color = m_myColor.getUserColor(dwPenColor);
            }
            return color;
        }

        /// <summary>
        /// 获取要绘制的颜色
        /// </summary>
        /// <param name="dwPenColor">输入颜色</param>
        /// <returns>输出颜色</returns>
        public override long getPaintColor(long dwPenColor)
        {
            dwPenColor = getColor(dwPenColor);
            return dwPenColor;
        }

        /// <summary>
        /// 是否允许反色
        /// </summary>
        public bool m_allowReverseColor = true;

        /// <summary>
        /// 获取偏移
        /// </summary>
        /// <returns>偏移坐标</returns>
        public override FCPoint getOffset()
        {
            return new FCPoint(m_offsetX, m_offsetY);
        }

        /// <summary>
        /// 获取缩放比例
        /// </summary>
        /// <param name="scaleFactorX">横向缩放比例</param>
        /// <param name="scaleFactorY">纵向缩放比例</param>
        public override void getScaleFactor(ref double scaleFactorX, ref double scaleFactorY)
        {
            scaleFactorX = m_scaleFactorX;
            scaleFactorY = m_scaleFactorY;
        }

        /// <summary>
        /// 旋转角度
        /// </summary>
        /// <param name="op">圆心坐标</param>
        /// <param name="mp">点的坐标</param>
        /// <param name="angle">角度</param>
        /// <returns>结果坐标</returns>
        public override FCPoint rotate(FCPoint op, FCPoint mp, int angle)
        {
            float PI = 3.14159265f;
            FCPoint pt = new FCPoint();
            pt.x = (int)((mp.x - op.x) * Math.Cos(angle * PI / 180) - (mp.y - op.y) * Math.Sin(angle * PI / 180) + op.x);
            pt.y = (int)((mp.x - op.x) * Math.Sin(angle * PI / 180) + (mp.y - op.y) * Math.Cos(angle * PI / 180) + op.y);
            return pt;
        }

        /// <summary>
        /// 设置裁剪区域
        /// </summary>
        /// <param name="rect">区域</param>
        public override void setClip(FCRect rect)
        {
            if (m_isClip)
            {
                m_canvas.Restore();
                m_isClip = false;
            }
            SKRect skRect = new SKRect(rect.left + m_offsetX, rect.top + m_offsetY, rect.right + m_offsetX, rect.bottom + m_offsetY);
            affectScaleFactor(ref skRect);
            if (skRect.Width > 0 && skRect.Height > 0)
            {
                m_canvas.Save();
                m_canvas.ClipRect(skRect);
                m_isClip = true;
            }
        }

        /// <summary>
        /// 设置直线两端的样式
        /// </summary>
        /// <param name="startLineCap">开始的样式</param>
        /// <param name="endLineCap">结束的样式</param>
        public override void setLineCap(int startLineCap, int endLineCap)
        {
          
        }

        /// <summary>
        /// 设置偏移
        /// </summary>
        /// <param name="mp">偏移坐标</param>
        public override void setOffset(FCPoint mp)
        {
            m_offsetX = mp.x;
            m_offsetY = mp.y;
        }

        /// <summary>
        /// 设置透明度
        /// </summary>
        /// <param name="opacity">透明度</param>
        public override void setOpacity(float opacity)
        {
            if (m_opacity != opacity)
            {
                m_opacity = opacity;
            }
        }

        /// <summary>
        /// 设置缩放因子
        /// </summary>
        /// <param name="scaleFactorX">横向因子</param>
        /// <param name="scaleFactorY">纵向因子</param>
        public override void setScaleFactor(double scaleFactorX, double scaleFactorY)
        {
            m_scaleFactorX = scaleFactorX;
            m_scaleFactorY = scaleFactorY;
        }

        /// <summary>
        /// 设置资源的路径
        /// </summary>
        /// <param name="resourcePath">资源的路径</param>
        public override void setResourcePath(String resourcePath)
        {
            m_resourcePath = resourcePath;
        }

        /// <summary>
        /// 设置旋转角度
        /// </summary>
        /// <param name="rotateAngle">旋转角度</param>
        public override void setRotateAngle(int rotateAngle)
        {
            m_rotateAngle = rotateAngle;
        }

        /// <summary>
        /// 设置是否支持透明色
        /// </summary>
        /// <returns>是否支持</returns>
        public override bool supportTransparent()
        {
            return true;
        }

        /// <summary>
        /// 获取文字大小
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>z
        /// <returns>字体大小</returns>
        public override FCSize textSize(String text, FCFont font, int width)
        {
            FCSizeF tSize = textSizeF(text, font, width);
            return new FCSize((int)tSize.cx, (int)tSize.cy);
        }

        /// <summary>
        /// 获取文字大小
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>
        /// <returns>字体大小</returns>
        public override FCSizeF textSizeF(String text, FCFont font, int width)
        {
            String fontFamily = font.m_fontFamily;
            String newFont = "";
            if (fontFamily == "Default")
            {
                newFont = MyColor.getSystemFont();  
            }
            else
            {
                newFont = font.m_fontFamily;
            }
            float rate = (float)((m_scaleFactorX + m_scaleFactorY) / 2);
            m_paint.TextSize = font.m_fontSize * rate + 2;
            if (m_font.FamilyName != newFont)
            {
                m_paint.Typeface = SKTypeface.FromFamilyName(newFont);
            }
            SKFontMetrics fm = m_paint.FontMetrics;
            FCSizeF size = new FCSizeF((float)Math.Round(m_paint.MeasureText(text) / rate, 2), (float)(Math.Round((fm.Descent - fm.Ascent) / rate, 2)));
            return size;
        }
    }
}